package syM

import (
	"fmt"
	"db2s/Meta"
	"db2s/go-log/log"
	"db2s/parDef"
	mq "db2s/topic-mq"
)

func objectBaseQuery(message mq.Message) (err error) {
	var plan = message.Properties["plan"].(*SchedulePlan2)
	var objectMeta = &GetObjectMeta{}
	if objectMeta.AlterStatus, err = objectJoinMatch(plan); err != nil {
		return err
	}
	if !sendMsg(getCheckMod(), ObjectIsJobMeta, getTableName(plan.Object.Schema, plan.Object.Table), getMsgSendData(plan, map[string]any{
		"logSeq": plan.Object.ObjectLogSeq, "objectMeta": objectMeta, "topic": ObjectIsJobMeta,
	})) {
		return fmt.Errorf("send msg fail")
	}
	plan.MQ.FirstObjectProductSwap(1)
	plan.MQ.SpeedLimitSwitch = false
	plan.MQ.FirstMsgProductAdd()
	plan.MQ.FirstMsgFinishMarkSwap()
	plan.MQ.SecondMsgProductAdd()
	plan.MQ.SecondMsgFinishMarkSwap()
	return
}

func joinObjectMetaChoose(meta *GetObjectMeta, object string) (result []any) {
	switch object {
	case "seq":
		if meta.SeqResult != nil {
			return meta.SeqResult.([]any)
		}
		return nil
	}
	return
}
func objectSeqMetaData(message mq.Message) (result any, err error) {
	var objectMeta = message.Properties["objectMeta"].(*GetObjectMeta)
	var plan = message.Properties["plan"].(*SchedulePlan2)
	var res []any
	if GlobalPConfigs.rules.Object.Drop && objectMeta.AlterStatus {
		if _, err = dropObject(plan); err != nil {
			return
		}
		objectMeta.AlterStatus = false
	}
	c := Meta.NewMeta([]string{GlobalPConfigs.dSns.SrcDBName, GlobalPConfigs.dSns.DestDBName}, "join", plan.Object.Role)
	c.Parameter1 = append(c.Parameter1, parDef.Parameter{Con: GlobalPConfigs.db.Source.GetDB("single"), Object: parDef.Object{Schema: plan.Object.Schema, Table: plan.Object.Table}})
	c.Parameter1 = append(c.Parameter1, parDef.Parameter{Con: GlobalPConfigs.db.Target.GetDB("single"), Object: parDef.Object{Schema: plan.Object.MSchema, Table: plan.Object.MTable}})
	if result, err = c.GetSeqMetaST(); err != nil {
		return
	}
	switch q := result.(type) {
	case []any:
		for _, v := range q {
			if v != nil {
				res = append(res, v)
			} else {
				res = append(res, v)
			}
		}
	}
	result = res
	return
}

func createObjectGeneralSql(plan *SchedulePlan2, c *Meta.Meta) (triggerGeneralCreate any, err error) {
	c.Join = "right"
	var event = "[createGeneralSql]"
	if triggerGeneralCreate, err = c.GetSeqCreateST(); err != nil {
		errorAction(plan, err, fmt.Sprintf("(%v) %v The exec create table sql for generating Target table %v failed! error Msg: %v", plan.Object.ObjectLogSeq, event, getTableName(plan.Object.Schema, plan.Object.Table), err))
	}
	return
}

func (sp SchedulePlan2) objectCreateFixSql(plan *SchedulePlan2, meta *GetObjectMeta) (result []fixSqlResult, err error) {
	var splitMeta []any
	var sourcePrintCreate, triggerGeneralCreate any
	var event = "[objectCreateFixSql]"
	log.MainLog().Info(fmt.Sprintf("(%v) %v Start generating the creation statement for Table %v", plan.Object.ObjectLogSeq, event, getTableName(plan.Object.Schema, plan.Object.Table)))
	if splitMeta = joinObjectMetaChoose(meta, "seq"); splitMeta == nil {
		errorAction(plan, err, fmt.Sprintf("(%v) %v The base data cutting of the source table %v failed. error Msg: %v", plan.Object.ObjectLogSeq, event, getTableName(plan.Object.Schema, plan.Object.Table), err))
		return
	}
	plan.TPod.Object.ExecObject = "create"
	c := Meta.NewMeta([]string{GlobalPConfigs.dSns.SrcDBName, GlobalPConfigs.dSns.DestDBName}, "left", plan.Object.Role)
	c.Parameter1 = append(c.Parameter1, parDef.Parameter{Con: GlobalPConfigs.db.Source.GetDB("single"), Meta: splitMeta[0], Object: parDef.Object{Schema: plan.Object.Schema, Table: plan.Object.Table}})
	c.Parameter1 = append(c.Parameter1, parDef.Parameter{Con: GlobalPConfigs.db.Target.GetDB("single"), Meta: splitMeta[0], Object: parDef.Object{Schema: plan.Object.MSchema, Table: plan.Object.MTable}})
	if sourcePrintCreate, err = createObjectPrintSql(plan, c); err != nil {
		return
	}
	if triggerGeneralCreate, err = createObjectGeneralSql(plan, c); err != nil {
		return
	}
	result = append(result, fixSqlResult{
		createSql: triggerGeneralCreate,
		printSql:  sourcePrintCreate,
	})
	log.MainLog().Info(fmt.Sprintf("(%v) %v The create object statement of Table %v was generated successfully.", plan.Object.ObjectLogSeq, event, getTableName(plan.Object.Schema, plan.Object.Table)))
	return
}
